package Core;
/*
 *  SoundManager version 1.0.2
 *  Van Tan Tai (C) 2010 (6-6-2011)
 *  Note: beta version
 */

import java.io.IOException;
import java.io.InputStream;
import javax.microedition.media.Manager;
import javax.microedition.media.MediaException;
import javax.microedition.media.Player;
import javax.microedition.media.control.VolumeControl;

import Const.IDSound;

public class Sound {
	
	public static Sound ins = null;
	public final static int LOOP_FOREVER = -1;
	public final static int LOOP_ONETIMES = 1;

	private boolean isEnable	= false;

	private Player player[]		= null;
	private int iVolume			= 100;
	private int idSoundResumed	= -1;
	private int iResumeLoopC	= 1;
	
	public Sound() {
		player = new Player[IDSound.COUNT];
	}
	
	/** isAutoResumeIfEnable: true[main menu, play game...] ; false[in game menu] */
	public boolean ONOFF_Switch(boolean isAutoResumeIfEnable){
		setEnable(!isEnable);
		
		if(isEnable){
			if(!isAutoResumeIfEnable) return isEnable;
			if(isPlaying(idSoundResumed))
				return isEnable;
			resume();
		} else {
			stopAll();
		}
		return isEnable;
	}
	
	public boolean isEnable(){
		return isEnable;
	}
	
	public void setEnable(boolean isEnable){
		this.isEnable=isEnable;
	}
	
	public void load(int index, int loopCount) {	
		try {
			
			// init player
			if (player[index] != null) {
				try {
					if (player[index].getState() == Player.STARTED)			player[index].stop();
					if (player[index].getState() == Player.PREFETCHED)		player[index].deallocate();
					if (player[index].getState() == Player.REALIZED 
						|| player[index].getState() == Player.UNREALIZED)	player[index].close();
				} catch (Exception e) {
					e.printStackTrace();
				}
				
				player[index] = null;
				System.gc();
			}

			//create player
			String sName = IDSound.sFile[index];
			String sType = "audio/x-wav";
			String sExt = sName.substring(sName.length()-3).toLowerCase();
			if(sExt.equals("mid"))
				sType = "audio/midi";
			else if(sExt.equals("mmf"))
				sType = "audio/x-smaf";
			else if(sExt.equals("wav"))
				sType = "audio/x-wav";
			else if(sExt.equals("mp3"))
				sType = "audio/mpeg";
			InputStream in = getClass().getResourceAsStream(IDSound.stSoundPath + sName);
			if(in == null) return;
			player[index] = Manager.createPlayer(in, sType);
			
			// prepare to play
			if (player[index].getState() != Player.REALIZED)
				player[index].realize();
			if (player[index].getState() != Player.PREFETCHED)
				player[index].prefetch();
			
			// Volume
			VolumeControl volume = (VolumeControl) player[index].getControl("VolumeControl");
			volume.setLevel(iVolume);
			
			// Loop
			player[index].setLoopCount(loopCount);
			
		} catch (MediaException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public void playBackground(int index, int loopCount){
		idSoundResumed = index;
		iResumeLoopC = loopCount;
		if (isEnable==false)
			return;
		if(isPlaying(index))
			return;
		if(player[index] == null){
			load(index, loopCount);
			System.out.println(">>> load sound Background");
		}
		play(index);
	}
	
	public void resume(){
		if(!isEnable || idSoundResumed < 0 || idSoundResumed >= IDSound.COUNT)
			return;
		if(player[idSoundResumed] == null)
			playBackground(idSoundResumed, iResumeLoopC);
		else
			play(idSoundResumed);
	}
	
	public int setVolume(int index, int Value){
		if(Value < 0 || Value > 100) return -1;
		if(player[index] == null) return -1;
		if(Value > iVolume) Value = iVolume;
		VolumeControl volume = (VolumeControl) player[index].getControl("VolumeControl");
		return volume.setLevel(Value);
	}
	
	public int getVolume(int index){
		if(player[index] == null) return -1;
		VolumeControl volume = (VolumeControl) player[index].getControl("VolumeControl");
		return volume.getLevel();
	}
	
	public int getMasterrVolume(){
		return iVolume;
	}
	
	public void setMasterVolume(int volume){
		iVolume = volume;
		for(int i = 0; i < IDSound.COUNT; i++)
			setVolume(i, iVolume);
	}
	
	public void play(int index) {
		if(!isEnable) return;
		try {
			if (player[index] != null) {
				player[index].start();
			}
			else {
				load(index, LOOP_ONETIMES);
				if (player[index] != null)
					player[index].start();
			}
			
		} catch (MediaException e) {
			e.printStackTrace();
		}
	}

	public void stop(int index) {
		try {
			if (player[index] != null) {
				player[index].stop();
//				if(player[index].getState() == Player.PREFETCHED || player[index].getState() == Player.STARTED){
//					player[index].deallocate(); //TODO: not fixed yet!
//				}
			}
		} catch (MediaException e) {
			e.printStackTrace();
		}		
	}
	
	
	public void stopAll(){
		for(int i = 0; i < IDSound.COUNT; i++)
			stop(i);
	}
	
	public boolean isPlaying(int index) {
		if (player[index] != null) {
			return player[index].getState() == Player.STARTED;
		} else {
			return false;
		}
	}
	
	public void close(int index) {
		if (player[index] != null) {
			try {
				player[index].stop();
				player[index].close();
				player[index] = null;
				System.gc();
			}
			catch (MediaException e) {
				e.printStackTrace();
			}
		}
	}
	
	public void destroy(){
		try {
			for(int i = 0; i < IDSound.COUNT; i++){
				if (player[i] != null) {
					player[i].stop();
					player[i].close();
					player[i] = null;
				}
			}
			System.gc();
		}
		catch (MediaException e) {
			System.out.println("ERROR="+e);
		}
	}
}